﻿using Sidvall.IO;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Sidvall.Web.IO
{
    public class FolderManager
    {
        #region Public Members

        #region Create

        public async Task<bool> CreateFolderAsync(string storeId, string path, CancellationToken cancellationToken)
        {
            var store = Sidvall.Web.IO.SystemContext.Current.FileSystemContext.Stores.FindStore(storeId);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.AddItems, path).ConfigureAwait(false);
            var fs = await SystemContext.Current.FileSystemFactory.CreateAsync(store).ConfigureAwait(false);
            return await fs.CreateFolderAsync(path, cancellationToken).ConfigureAwait(false);
        }

        #endregion
        #region Delete

        public async Task<bool> DeleteFolderAsync(string storeId, string path, bool recursive, CancellationToken cancellationToken)
        {
            var store = Sidvall.Web.IO.SystemContext.Current.FileSystemContext.Stores.FindStore(storeId);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.DeleteItems, path).ConfigureAwait(false);
            var fs = await SystemContext.Current.FileSystemFactory.CreateAsync(store).ConfigureAwait(false);
            return await fs.DeleteFolderAsync(path, recursive, cancellationToken).ConfigureAwait(false);
        }

        #endregion
        #region Exists

        public async Task<bool> FolderExistsAsync(string storeId, string path, CancellationToken cancellationToken)
        {
            var store = Sidvall.Web.IO.SystemContext.Current.FileSystemContext.Stores.FindStore(storeId);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.GetItemsMetadata, path).ConfigureAwait(false);
            var fs = await SystemContext.Current.FileSystemFactory.CreateAsync(store).ConfigureAwait(false);
            return await fs.FolderExistsAsync(path, cancellationToken).ConfigureAwait(false);
        }

        #endregion
        #region GetItem

        public async Task<Folder> GetFolderAsync(string storeId, string folderName, bool loadFolderDetails, CancellationToken cancellationToken)
        {
            var store = Sidvall.Web.IO.SystemContext.Current.FileSystemContext.Stores.FindStore(storeId);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.GetItemsMetadata, folderName).ConfigureAwait(false);
            var fs = await SystemContext.Current.FileSystemFactory.CreateAsync(store).ConfigureAwait(false);
            return await fs.GetFolderAsync(folderName, loadFolderDetails, cancellationToken).ConfigureAwait(false);
        }

        #endregion
        #region GetItems

        public async Task<IEnumerable<Folder>> GetFoldersAsync(string storeId, string path, string searchPattern, SearchOption searchOption, bool loadFolderDetails, CancellationToken cancellationToken)
        {
            var store = Sidvall.Web.IO.SystemContext.Current.FileSystemContext.Stores.FindStore(storeId);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.GetItemsMetadata, path).ConfigureAwait(false);
            var fs = await SystemContext.Current.FileSystemFactory.CreateAsync(store).ConfigureAwait(false);
            return await fs.GetFoldersAsync(path, searchPattern, searchOption, loadFolderDetails, cancellationToken).ConfigureAwait(false);
        }

        #endregion
        #region GetNames

        public async Task<IEnumerable<string>> GetFolderNamesAsync(string storeId, string path, string searchPattern, SearchOption searchOption, CancellationToken cancellationToken)
        {
            var store = Sidvall.Web.IO.SystemContext.Current.FileSystemContext.Stores.FindStore(storeId);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.GetItemsMetadata, path).ConfigureAwait(false);
            var fs = await SystemContext.Current.FileSystemFactory.CreateAsync(store).ConfigureAwait(false);
            return await fs.GetFolderNamesAsync(path, searchPattern, searchOption, cancellationToken).ConfigureAwait(false);
        }

        #endregion
        #region Move

        public async Task<bool> MoveFolderAsync(string storeId, string sourceFolderName, string destinationFolderName, bool deleteExistingFolder, CancellationToken cancellationToken)
        {
            var store = Sidvall.Web.IO.SystemContext.Current.FileSystemContext.Stores.FindStore(storeId);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.SaveItems, sourceFolderName).ConfigureAwait(false);
            await SystemContext.Current.ThrowIfNotAuthorizedAsync(store, Sidvall.IO.Security.DomainObjects.Folder, Sidvall.Security.Operations.SaveItems, destinationFolderName).ConfigureAwait(false);
            var fs = await SystemContext.Current.FileSystemFactory.CreateAsync(store).ConfigureAwait(false);
            return await fs.MoveFolderAsync(sourceFolderName, destinationFolderName, deleteExistingFolder, cancellationToken).ConfigureAwait(false);
        }

        #endregion

        #endregion
    }
}
